package online.longzipeng.mywebdemo.mq.consumer;

import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Map;

/**
 * @Author: lzp
 * @Description: 简单模式消
 * 一个队列两端对应生产者和消费者，1V1
 * @Date: 2024/1/10 10:31
 */
@Component
//@RabbitListener(queues = "my_queue")//监听的队列名称
//@RabbitListener(queuesToDeclare = @Queue("my_queue"))  //如果simple_queue队列不存在，则创建simple_queue队列。默认队列是持久化，非独占式的
public class SimpleConsumer {

	//消费者如果监听到消息队列有消息传入，则会自动消费
//	@RabbitHandler
//	public void receive(Map message, Channel channel) {
//		System.out.println("简单模式 -> 消费者收到map类型消息  : " + message.toString());
//	}
//
//	@RabbitHandler
//	public void receive2(String message, Channel channel) {
//		System.out.println("简单模式 -> 消费者收到string类型消息  : " + message.toString());
//	}

	// 实测，简单模式配置手动提交以后，@RabbitListener得加在方法上才能处理请求，
	// @RabbitListener 加在类上，在自动提交的情况下，可以根据发送消息的参数类型，对应调用相同入参的方法处理
	@RabbitListener(queuesToDeclare = @Queue("my_queue"))
	public void process(Message message, Channel channel) throws IOException {
		String str = new String(message.getBody());
		JSONObject msgData = JSONUtil.parseObj(str);
		Object messageId = msgData.getByPath("messageId");
		if (null==messageId || messageId.toString().equals("")) {
			/**
			 * 有异常就拒收消息
			 * basicNack(long deliveryTag, boolean multiple, boolean requeue)
			 * deliveryTag:当前消息在队列中的的索引;
			 * multiple:为true的话就是批量确认 【deliveryTag小于当前消息的全部确认】
			 * requeue:true将消息重返当前消息队列,重新发送给消费者;
			 *         false将消息丢弃
			 */
			channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
			System.out.println("简单模式 -> 消费者拒收消息 : " + msgData.toString());
		}else {
			/**
			 * 没有异常就确认消息
			 * basicAck(long deliveryTag, boolean multiple)
			 * deliveryTag:当前消息在队列中的的索引;
			 * multiple:为true的话就是批量确认
			 */
			channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
			System.out.println("简单模式 -> 消费者收到消息  : " + msgData.toString());
		}
	}

}